﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpShare.Storage;
using SharpShare.Storage.Security;

namespace SharpShare.Afp.Protocol.Handlers {
    internal class AfpListExtAttributesRequestHandler : IAfpRequestHandler {
        public byte CommandCode {
            get { return 72; }
        }

        public AfpResultCode Process(IAfpSession session, DsiHeader dsiHeader, AfpStream requestStream, AfpStream responseStream) {
            requestStream.ReadPadding();

            ushort volumeId = requestStream.ReadUInt16();
            uint directoryID = requestStream.ReadUInt32();
            AfpExtendedAttributesBitmap fileBitmap = requestStream.ReadEnum<AfpExtendedAttributesBitmap>();
            short requestCount = requestStream.ReadInt16();
            int startIndex = requestStream.ReadInt32();
            int maxReplySize = requestStream.ReadInt32();
            IAfpVolume volume;
            IStorageItem item = requestStream.ReadPathAndFind(session, volumeId, directoryID, out volume).DemandExists();

            item.GetEffectiveAccess(session).DemandRight(StorageAccessRight.GetMetadata);

            var names = item.ListMetadata()
                .Where(m => m.StartsWith(AfpSetExtAttributeRequestHandler.CustomMetadataNamePrefix))
                .Select(m => m.Remove(0, AfpSetExtAttributeRequestHandler.CustomMetadataNamePrefix.Length));

            AfpStream attrNamesStream = new AfpStream();
            foreach (string name in names) {
                attrNamesStream.WriteBytes(System.Text.Encoding.UTF8.GetBytes(name));
                attrNamesStream.WriteBytes(new byte[] { 0 });
            }

            responseStream.WriteEnum(fileBitmap);
            responseStream.WriteUInt32((uint)attrNamesStream.Stream.Length);

            if (maxReplySize > 0) {
                if (maxReplySize < (attrNamesStream.Stream.Length + 6)) {
                    return AfpResultCode.FPParamErr;
                }

                responseStream.WriteBytes(attrNamesStream.ToByteArray());
            }

            return AfpResultCode.FPNoErr;
        }
    }
}
